package com.wxy.school.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wxy.school.common.R;
import com.wxy.school.dto.CategoryDto;
import com.wxy.school.dto.DishDto;
import com.wxy.school.entity.Category;
import com.wxy.school.entity.Dish;
import com.wxy.school.entity.DishFlavor;
import com.wxy.school.entity.Shop;
import com.wxy.school.service.CategoryService;
import com.wxy.school.service.DishFlavorService;
import com.wxy.school.service.DishService;
import com.wxy.school.service.ShopService;
import com.wxy.school.utils.BaseContext;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@RequestMapping("school/category")
@RestController
public class CategoryController {

    @Resource
    private CategoryService categoryService;

    @Resource
    private ShopService shopService;

    @Resource
    private DishService dishService;

    @Resource
    private DishFlavorService dishFlavorService;

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * @description: 获取所有菜品分类列表
     * @author: 王祥宇
     * @param: pageNum 查询页数
     * @param: pageSize 每页查询数据条数
     * @param: qurey 模糊查询参数
     * @return: com.wxy.school.common.R<com.baomidou.mybatisplus.extension.plugins.pagination.Page>
     */
    @GetMapping("/getList")
    public R<Page> getCategory(int pageNum, int pageSize, String qurey){
        //构建分页查询器
        Page<Category> page = new Page(pageNum, pageSize);
        Page<CategoryDto> categoryDtoPage = new Page<>();
        //构建查询条件
        LambdaQueryWrapper<Category> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //当qurey不为空时添加该查询条件
        lambdaQueryWrapper.like(StringUtils.isNotEmpty(qurey), Category::getCategoryName, qurey);
        //根据创建时间进行排序
        lambdaQueryWrapper.orderByAsc(Category::getCreateTime);
        //执行查询
        categoryService.page(page, lambdaQueryWrapper);
        BeanUtils.copyProperties(page, categoryDtoPage, "records");
        List<Category> records = page.getRecords();
        List<CategoryDto> categoryDtoList = records.stream().map((item) -> {
            CategoryDto categoryDto = new CategoryDto();
            BeanUtils.copyProperties(item, categoryDto);
            Long id = item.getShopId();
            Shop shop = shopService.getById(id);
            categoryDto.setShopName(shop.getShopName());
            return categoryDto;
        }).collect(Collectors.toList());
        categoryDtoPage.setRecords(categoryDtoList);
        //返回查询结果
        return R.success(categoryDtoPage);
    }

    /**
     * @description: 添加菜品
     * @author: 王祥宇
     * @param: map
     * @param: category
     * @return: com.wxy.school.common.R<java.lang.String>
     */
    @PostMapping("/addCategory")
    public R<String> addCategory(@RequestBody CategoryDto categoryDto){
        //将用户名存储到线程中
        BaseContext.setThreadLocal(categoryDto.getUserName());
        Category category = new Category();
        BeanUtils.copyProperties(categoryDto, category, "userName");
        //创建查询条件
        LambdaQueryWrapper<Category> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Category::getCategoryName, categoryDto.getCategoryName());
        //执行查询
        Category category1 = categoryService.getOne(lambdaQueryWrapper);
        if (category1 == null || !Objects.equals(category1.getShopId(), categoryDto.getShopId())){
            categoryService.save(category);
            return R.success("菜品分类添加成功");
        }else {
            return R.error("菜品信息添加失败");
        }
    }

    /**
     * @description: 根据id进行查询
     * @author: 王祥宇
     * @param: id
     * @return: com.wxy.school.common.R<com.wxy.school.entity.Category>
     */
    @GetMapping("/{id}")
    public R<Category> getById(@PathVariable Long id){
        Category category = categoryService.getById(id);
        return R.success(category);
    }

    /**
     * @description: 根据shopId进行查询
     * @author: 王祥宇
     * @param: id
     * @return: com.wxy.school.common.R<com.wxy.school.entity.Category>
     */
    @GetMapping("/getByShopId")
    public R<List<CategoryDto>> getByShopId(Long shopId, Long userId){
        // 拼接键名
        String key = "userId" + "_" + userId + "-" + "shopId" + "_" + shopId;
        // 根据键名在Redis缓存中查询数据
        List<CategoryDto> categoryDtoList = (List<CategoryDto>) redisTemplate.opsForValue().get(key);
        // 若Redis有数据则直接返回数据给前端
        if (categoryDtoList != null){
            return R.success(categoryDtoList);
        }
        // 若Redis中找不到数据 则在数据库中查询
        LambdaQueryWrapper<Category> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Category::getShopId, shopId);
        // 根据shopId查询该店铺下的所有分类信息
        List<Category> categoryList = categoryService.list(lambdaQueryWrapper);
        // 使用stream流遍历所有分类信息
        categoryDtoList = categoryList.stream().map((item) ->{
            CategoryDto categoryDto = new CategoryDto();
            BeanUtils.copyProperties(item, categoryDto);
            Long categoryId = item.getId();
            // 根据分类id在dish表中查询该分类下的所有菜品信息
            LambdaQueryWrapper<Dish> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
            lambdaQueryWrapper1.eq(Dish::getCategoryId, categoryId);
            List<Dish> dishList = dishService.list(lambdaQueryWrapper1);
            // 使用stream流遍历所有的菜品信息
            List<DishDto> dishDtoList = dishList.stream().map((it) ->{
                DishDto dishDto = new DishDto();
                BeanUtils.copyProperties(it, dishDto);
                Long dishId = it.getId();
                // 根据菜品id在dish_flavor表中查询该菜品下的所有口味信息
                LambdaQueryWrapper<DishFlavor> lambdaQueryWrapper2 = new LambdaQueryWrapper<>();
                lambdaQueryWrapper2.eq(DishFlavor::getDishId, dishId);
                List<DishFlavor> dishFlavors = dishFlavorService.list(lambdaQueryWrapper2);
                dishDto.setDishFlavore(dishFlavors);
                return dishDto;
            }).collect(Collectors.toList());
            categoryDto.setDishDtoList(dishDtoList);
            return categoryDto;
        }).collect(Collectors.toList());
        // 将查询到的分类信息存到Redis缓存中 便于下次查询使用
        redisTemplate.opsForValue().set(key, categoryDtoList);
        return R.success(categoryDtoList);
    }

    /**
     * @description: 修改菜品分类信息
     * @author: 王祥宇
     * @param: map
     * @param: category
     * @return: com.wxy.school.common.R<java.lang.String>
     */
    @PostMapping("/updateCategory")
    public R<String> updateCategory(@RequestBody Map map, Category category){
        //获取分类名称
        String categoryName = map.get("categoryName").toString();
        //获取描述内容
        String categoryInfo = map.get("categoryInfo").toString();
        //获取当前登录用户名
        String userName = map.get("userName").toString();
        //获取用户id
        String ids = map.get("id").toString();
        Long id = Long.parseLong(ids);
        //将用户名存储到线程中
        BaseContext.setThreadLocal(userName);
        //将修改后的内容存储到对象中
        category.setId(id);
        category.setCategoryName(categoryName);
        category.setCategoryInfo(categoryInfo);
        categoryService.updateById(category);
        return R.success("分类信息修改成功");
    }

    /**
     * @description: 删除菜品分类
     * @author: 王祥宇
     * @param: id
     * @return: com.wxy.school.common.R<java.lang.String>
     */
    @DeleteMapping("/deleteCategory/{id}")
    public R<String> delete(@PathVariable Long id){
        categoryService.removeById(id);
        return R.success("菜品分类删除成功");
    }
}
